package com.gzstv.dlnasdk;

import android.Manifest;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.android.material.textfield.TextInputEditText;
import com.gzstv.dlnasdk.upnp.Device;

import java.io.IOException;

public class MainActivity extends AppCompatActivity implements DLNAManager.DLNAManagerCallback {

    private static final int PICK_VIDEO_REQUEST = 1;
    private static final int PERMISSION_REQUEST_CODE = 100;

    private TextView selectedDeviceTextView;
    private Button selectDeviceButton;
    private TextInputEditText videoUrlEditText;
    private Button castButton;
    private Button playButton;
    private Button pauseButton;
    private Button stopButton;
    private Button selectLocalVideoButton;

    private ScrollView errorScrollView;
    private TextView errorDetailsTextView;
    private Button copyErrorButton;

    private Device selectedDevice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        selectedDeviceTextView = findViewById(R.id.selectedDeviceTextView);
        selectDeviceButton = findViewById(R.id.selectDeviceButton);
        videoUrlEditText = findViewById(R.id.videoUrlEditText);
        castButton = findViewById(R.id.castButton);
        playButton = findViewById(R.id.playButton);
        pauseButton = findViewById(R.id.pauseButton);
        stopButton = findViewById(R.id.stopButton);
        selectLocalVideoButton = findViewById(R.id.selectLocalVideoButton);

        errorScrollView = findViewById(R.id.errorScrollView);
        errorDetailsTextView = findViewById(R.id.errorDetailsTextView);
        copyErrorButton = findViewById(R.id.copyErrorButton);

        DLNAManager.getInstance().setCallback(this);
        updateSelectedDeviceText();

        // Check for crash info on app start
        String lastCrashInfo = DLNAApplication.getLastCrashInfo(this);
        Log.e("DLNAApplication","Last crash info: " + lastCrashInfo);
        if (lastCrashInfo != null) {
            showErrorDetails(lastCrashInfo);
            DLNAApplication.clearLastCrashInfo(this);
        }

        selectDeviceButton.setOnClickListener(v -> {
            //int index = 6/0
            DeviceSelectionDialogFragment dialogFragment = new DeviceSelectionDialogFragment();
            dialogFragment.setOnDeviceSelectedListener(device -> {
                selectedDevice = device;
                DLNAManager.getInstance().setSelectedDevice(device);
                updateSelectedDeviceText();
                Toast.makeText(MainActivity.this, getString(R.string.selected_device_prefix) + device.getFriendlyName(), Toast.LENGTH_SHORT).show();
            });
            dialogFragment.show(getSupportFragmentManager(), "DeviceSelectionDialog");
        });

        castButton.setOnClickListener(v -> {
            String videoUrl = videoUrlEditText.getText().toString();
            if (videoUrl.isEmpty()) {
                Toast.makeText(MainActivity.this, R.string.please_enter_url_or_select_local, Toast.LENGTH_SHORT).show();
                return;
            }
            if (selectedDevice == null) {
                Toast.makeText(MainActivity.this, R.string.no_device_selected, Toast.LENGTH_SHORT).show();
                return;
            }
            DLNAManager.getInstance().cast(videoUrl, ""); // Empty metadata for now
        });

        playButton.setOnClickListener(v -> {
            if (selectedDevice == null) {
                Toast.makeText(MainActivity.this, getString(R.string.no_device_selected_error, getString(R.string.play)), Toast.LENGTH_SHORT).show();
                return;
            }
            DLNAManager.getInstance().play();
        });

        pauseButton.setOnClickListener(v -> {
            if (selectedDevice == null) {
                Toast.makeText(MainActivity.this, getString(R.string.no_device_selected_error, getString(R.string.pause)), Toast.LENGTH_SHORT).show();
                return;
            }
            DLNAManager.getInstance().pause();
        });

        stopButton.setOnClickListener(v -> {
            if (selectedDevice == null) {
                Toast.makeText(MainActivity.this, getString(R.string.no_device_selected_error, getString(R.string.stop)), Toast.LENGTH_SHORT).show();
                return;
            }
            DLNAManager.getInstance().stop();
        });

        selectLocalVideoButton.setOnClickListener(v -> {
            checkPermissionAndPickVideo();
        });

        copyErrorButton.setOnClickListener(v -> {
            ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            ClipData clip = ClipData.newPlainText("Error Details", errorDetailsTextView.getText());
            clipboard.setPrimaryClip(clip);
            Toast.makeText(MainActivity.this, "Error details copied to clipboard", Toast.LENGTH_SHORT).show();
        });
    }

    private void updateSelectedDeviceText() {
        if (selectedDevice != null) {
            selectedDeviceTextView.setText(getString(R.string.selected_device_prefix) + " " + selectedDevice.getFriendlyName());
        } else {
            selectedDeviceTextView.setText(R.string.no_device_selected);
        }
    }

    private void checkPermissionAndPickVideo() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
        } else {
            pickVideo();
        }
    }

    private void pickVideo() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("video/*");
        startActivityForResult(Intent.createChooser(intent, getString(R.string.select_video)), PICK_VIDEO_REQUEST);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                pickVideo();
            } else {
                Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_VIDEO_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri videoUri = data.getData();
            String videoPath = getPathFromUri(videoUri);
            if (videoPath != null) {
                videoUrlEditText.setText(videoPath);
            } else {
                Toast.makeText(this, R.string.could_not_get_video_path, Toast.LENGTH_SHORT).show();
            }
        }
    }

    private String getPathFromUri(Uri uri) {
        String path = null;
        String[] projection = { MediaStore.Video.Media.DATA };
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
                path = cursor.getString(column_index);
            }
            cursor.close();
        }
        return path;
    }

    private void showErrorDetails(String errorMessage) {
        errorDetailsTextView.setText(errorMessage);
        errorScrollView.setVisibility(View.VISIBLE);
        copyErrorButton.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        DLNAManager.getInstance().stopLocalServer(); // Stop local server when activity is destroyed
    }

    @Override
    public void onActionSuccess(String action) {
        runOnUiThread(() -> {
            errorScrollView.setVisibility(View.GONE);
            copyErrorButton.setVisibility(View.GONE);
            switch (action) {
                case "cast":
                    Toast.makeText(MainActivity.this, R.string.casting, Toast.LENGTH_SHORT).show();
                    break;
                case "play":
                    Toast.makeText(MainActivity.this, R.string.playing, Toast.LENGTH_SHORT).show();
                    break;
                case "pause":
                    Toast.makeText(MainActivity.this, R.string.pausing, Toast.LENGTH_SHORT).show();
                    break;
                case "stop":
                    Toast.makeText(MainActivity.this, R.string.stopping, Toast.LENGTH_SHORT).show();
                    break;
            }
        });
    }

    @Override
    public void onActionFailed(String action, String errorMessage) {
        runOnUiThread(() -> {
            showErrorDetails(errorMessage);
            switch (action) {
                case "cast":
                    Toast.makeText(MainActivity.this, getString(R.string.casting_failed, errorMessage), Toast.LENGTH_LONG).show();
                    break;
                case "play":
                    Toast.makeText(MainActivity.this, getString(R.string.play_failed, errorMessage), Toast.LENGTH_LONG).show();
                    break;
                case "pause":
                    Toast.makeText(MainActivity.this, getString(R.string.pause_failed, errorMessage), Toast.LENGTH_LONG).show();
                    break;
                case "stop":
                    Toast.makeText(MainActivity.this, getString(R.string.stop_failed, errorMessage), Toast.LENGTH_LONG).show();
                    break;
            }
        });
    }
}